package com.qys.livesMall.anchor.business;


import com.qys.livesMall.anchor.event.GiveGiftEvent;
import com.qys.livesMall.anchor.event.pojo.GiveGiftEventPOJO;
import com.qys.livesMall.anchor.model.dto.lives.app.ExchangeGoldDTO;
import com.qys.livesMall.anchor.model.dto.lives.app.GiveGiftDTO;
import com.qys.livesMall.anchor.model.entity.AnchorLivesGift;
import com.qys.livesMall.anchor.model.entity.AnchorLivesRoom;
import com.qys.livesMall.anchor.model.entity.AnchorLivesSession;
import com.qys.livesMall.anchor.model.vo.lives.app.GiftListVO;
import com.qys.livesMall.anchor.model.vo.lives.app.UserBalanceVO;
import com.qys.livesMall.anchor.service.AnchorLivesGiftService;
import com.qys.livesMall.anchor.service.AnchorLivesRoomService;
import com.qys.livesMall.anchor.service.AnchorLivesSessionService;
import com.qys.livesMall.app.user.service.AppUserGoldAccountService;
import com.qys.livesMall.app.user.service.IH2AppUserBalanceService;
import com.qys.livesMall.cache.RedisCache;
import com.qys.livesMall.common.exception.QysException;
import com.qys.livesMall.common.utils.MessageUtils;
import com.qys.livesMall.finance.service.FinanceBusinessService;
import com.qys.livesMall.framework.utils.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;

import static com.qys.livesMall.anchor.constants.RedisConstant.LIVE_ROOM_GIFT_LIST;

@Service
@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class LiveRoomGiftBusiness {

    private final ApplicationContext applicationContext;
    private final AppUserGoldAccountService userGoldAccountService;
    private final AnchorLivesGiftService anchorLivesGiftService;
    private final AnchorLivesRoomService anchorLivesRoomService;
    private final AnchorLivesSessionService anchorLivesSessionService;
    private final RedisCache redisCache;
    private final FinanceBusinessService financeBusinessService;
    private final IH2AppUserBalanceService userBalanceService;





    @Transactional(rollbackFor = Exception.class)
    public void giveGift(GiveGiftDTO giveDTO, Long userId) {
        userId = userId == null ? SecurityUtils.getUserId() : userId;
        log.info("用户直播赠送礼物,操作人：{}，操作信息：{}", userId, giveDTO);
        AnchorLivesGift livesGift = anchorLivesGiftService.getById(giveDTO.getId());
        if (null == livesGift) {
            throw new QysException("请检查ID");
        }
        //获取主播间数据
        AnchorLivesRoom anchorLivesRoom = anchorLivesRoomService.checkIsLive(giveDTO.getLivesRoomNum());

        AnchorLivesSession session = anchorLivesSessionService.getById(giveDTO.getLivesSessionId());
        if (session==null){
            throw new QysException(MessageUtils.message("直播间场次不存在"));
        }
        //总用的金币数量
        BigDecimal totalGold = livesGift.getGiftGold().multiply(BigDecimal.valueOf(giveDTO.getQuantity()));
        //根据房间号得到编号
        Long anchorId = anchorLivesRoom.getAnchorId();
        //调用扣除金币业务
        if (!userGoldAccountService.giveLivesGift(userId, totalGold)) {
            throw new QysException(MessageUtils.message("金币账户繁忙"));
        }
        applicationContext.publishEvent(new GiveGiftEvent(GiveGiftEventPOJO.builder()
                .livesGift(livesGift)
                .toAnchorId(anchorId)
                .livesSessionId(giveDTO.getLivesSessionId())
                .livesRoomId(anchorLivesRoom.getId())
                .quantity(giveDTO.getQuantity())
                .userId(userId)
                .livesRoomNum(anchorLivesRoom.getLivesRoomNum())
                .build()));
    }

    public List<GiftListVO> listGift(String livesRoomNum, Long livesSessionId) {
        /***获取缓存中礼物数据*/
        Map<String, GiftListVO> cacheMap = redisCache.getCacheMap(getGiftListKey(livesRoomNum, livesSessionId));
        return new TreeSet<>( cacheMap.values()).stream().toList();
    }

    private String getGiftListKey(String livesRoomNum, Long livesSessionId) {
        return LIVE_ROOM_GIFT_LIST + livesRoomNum + ":" + livesSessionId;
    }


    public void exchangeGold(ExchangeGoldDTO exchangeGoldDTO) {


        //TODO 调用兑换金币接口
        if (!userGoldAccountService.balanceExchangeGold(exchangeGoldDTO.getUserId(), exchangeGoldDTO.getExchangeGoldQuantity())) {
            throw new QysException(MessageUtils.message("金币账户繁忙"));
        }
    }

    public UserBalanceVO goldBalance() {
        UserBalanceVO userBalanceVO = new UserBalanceVO();
        userBalanceVO.setUserBalance(userBalanceService.queryByUserId(SecurityUtils.getUserId()).getBalance());
        userBalanceVO.setGoldAmount(userGoldAccountService.getGoldAccountByUserId(SecurityUtils.getUserId()).getGoldAmount());
        return userBalanceVO;
    }

    public BigDecimal exchangeGoldRatio() {
        return userGoldAccountService.exchangeGoldRatio();
    }


}
